﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using Caliburn.Micro;
using Wulong.Phone.Dianping.Helpers;
using Wulong.Phone.Dianping.Messages;
using Wulong.Phone.Dianping.Models;
using Wulong.Phone.Dianping.Services;

namespace Wulong.Phone.Dianping.ViewModels
{
    public class MainViewModel : DianpingViewModelBase, IHandle<RefreshMainView>
    {
        private readonly INavigationService _navigation;
        private readonly IWindowManager _windowManager;
        private IDisposable _disposablePromo;
        private IDisposable _disposableGroupOn;
        public MainViewModel(
            INavigationService navigation,
            IWindowManager windowManager
            )
        {
            _navigation = navigation;
            _windowManager = windowManager;
            _channelList = new ObservableCollection<Channel>();
            _hotPromotionList = new ObservableCollection<Promotion>();
            _groupOnList = new ObservableCollection<GroupOn>();
        }

        private bool _isPromoBusy;
        public bool IsPromoBusy { 
            get { return _isPromoBusy; } 
            set
            {
                _isPromoBusy = value;
                NotifyOfPropertyChange(()=>IsBusy);
            }}

        private bool _isGroupBusy;
        public bool IsGroupBusy
        {
            get { return _isGroupBusy; }
            set
            {
                _isGroupBusy = value;
                NotifyOfPropertyChange(()=>IsBusy);
            }
        }
        public bool IsBusy { get { return IsPromoBusy || IsGroupBusy; } }

        protected override void OnViewReady(object view)
        {
            base.OnViewReady(view);

            if(_channelList.Count==0)
                LoadChannels();
            if(_groupOnList.Count==0)
                LoadGroupOns();
            if(_hotPromotionList.Count == 0)
                LoadPromos();
        }

        private void LoadPromos()
        {
            IsPromoBusy = true;
            _disposablePromo = DianpingService.ObservablePromotion(CityCode)
                .ObserveOnDispatcher()
                .Finally(()=>IsPromoBusy=false)
                .Subscribe(item => _hotPromotionList.Add(item),
                           error => MessageHelper.ShowErrorMessage());
        }

        private void LoadGroupOns()
        {
            IsGroupBusy = true;
            _disposableGroupOn = DianpingService.ObservableHotGroupOn(CityPinyin)
                .ObserveOnDispatcher()
                .Finally(()=>IsGroupBusy=false)
                .Subscribe(item => _groupOnList.Add(item),
                           error => MessageHelper.ShowErrorMessage());
        }

        private void LoadChannels()
        {
            DianpingService
                .ObservableChannel(CityCode)
                .ObserveOnDispatcher()
                .Subscribe(item => _channelList.Add(item));
        }

        public string CityPinyin { get; set; }

        private Channel _selectedChannel;
        public Channel SelectedChannel
        {
            get { return _selectedChannel; }
            set
            {
                _selectedChannel = value;
                NotifyOfPropertyChange(() => SelectedChannel);
            }
        }

        private ObservableCollection<Channel> _channelList;
        public IEnumerable<Channel> ChannelList
        {
            get { return _channelList; }
        }

        private GroupOn _selectedGroupOn;
        public GroupOn SelectedGroupOn
        {
            get { return _selectedGroupOn; }
            set
            {
                _selectedGroupOn = value;
                NotifyOfPropertyChange(() => SelectedGroupOn);
            }
        }

        internal ObservableCollection<GroupOn> _groupOnList;
        public IEnumerable<GroupOn> GroupOnList
        {
            get { return _groupOnList; }
        }

        private Promotion _selectedPromo;
        public Promotion SelectedPromo
        {
            get { return _selectedPromo; }
            set
            {
                _selectedPromo = value;
                NotifyOfPropertyChange(() => SelectedPromo);
            }
        }

        internal ObservableCollection<Promotion> _hotPromotionList;
        public IEnumerable<Promotion> HotPromotionList
        {
            get { return _hotPromotionList; }
        }

        public void ViewChannel(Channel selectedItem)
        {
            if (selectedItem == null) return;
            _navigation.UriFor<MerchantsByChannelViewModel>()
                .WithParam(x=>x.ChannelId, (int)selectedItem.Id)
                .WithParam(x=>x.ChannelName, selectedItem.Name)
                .WithParam(x=>x.CityCode, CityCode)
                .Navigate();
        }

        public void ViewGroupOn(GroupOn selectedItem)
        {
            if (selectedItem == null) return;
            var vm = new GroupOnItemViewModel (selectedItem.Link);
            _windowManager.ShowDialog(vm);
        }

        public void ViewPromotion(Promotion selectedItem)
        {
            if (selectedItem == null) return;
            var vm = new PromotionItemViewModel(
                CityCode, 
                selectedItem.Id,
                _navigation)
                         {
                             PromotionItem = selectedItem
                         };
            _windowManager.ShowDialog(vm);
        }

        public void RefreshHotPromoList()
        {
            _hotPromotionList.Clear();
            LoadPromos();
        }

        public void RefreshGroupOnList()
        {
            _groupOnList.Clear();
            LoadGroupOns();
        }

        public void RefreshChannelList()
        {
            _channelList.Clear();
            LoadChannels();
        }

        public void SetMyCity()
        {
            _navigation.UriFor<YourCityViewModel>()
                .Navigate();
        }

        public void Handle(RefreshMainView message)
        {
            RefreshChannelList();
            RefreshGroupOnList();
            RefreshHotPromoList();
        }

        public void Search()
        {
            _navigation.UriFor<SearchViewModel>()
                .WithParam(x=>x.CityCode, CityCode)
                .Navigate();
        }

        protected override void OnDeactivate(bool close)
        {
            base.OnDeactivate(close);
            if(_disposableGroupOn!=null)
            _disposableGroupOn.Dispose();
            if(_disposablePromo!=null)
            _disposablePromo.Dispose();
        }

        public void ViewPromotionList()
        {
            _navigation.UriFor<PromotionListViewModel>()
                .WithParam(x=>x.CityCode, CityCode)
                .Navigate();
        }

        public void ViewGroupOnList()
        {
            _navigation.UriFor<GroupOnListViewModel>()
                .WithParam(x => x.CityCode, CityCode)
                .Navigate();
        }

        public void GoToAboutPage()
        {
            _navigation.UriFor<AboutViewModel>()
                .Navigate();
        }
    }
}
